define("gallery/juicer/0.6.4/juicer-debug", [], function(require, exports, module) {
    /*
    ********** Juicer **********
    ${A Fast template engine}
    Project Home: http://juicer.name

    Author: Guokai
    Gtalk: badkaikai@gmail.com
    Blog: http://benben.cc
    Licence: MIT License
    Version: 0.6.4-stable
*/
    (function() {
        // This is the main function for not only compiling but also rendering.
        // there's at least two parameters need to be provided, one is the tpl, 
        // another is the data, the tpl can either be a string, or an id like #id.
        // if only tpl was given, it'll return the compiled reusable function.
        // if tpl and data were given at the same time, it'll return the rendered 
        // result immediately.
        var juicer = function() {
            var args = [].slice.call(arguments);
            args.push(juicer.options);
            if (args[0].match(/^\s*#([\w:\-\.]+)\s*$/gim)) {
                args[0].replace(/^\s*#([\w:\-\.]+)\s*$/gim, function($, $id) {
                    var _document = document;
                    var elem = _document && _document.getElementById($id);
                    args[0] = elem ? elem.value || elem.innerHTML : $;
                });
            }
            if (arguments.length == 1) {
                return juicer.compile.apply(juicer, args);
            }
            if (arguments.length >= 2) {
                return juicer.to_html.apply(juicer, args);
            }
        };
        var __escapehtml = {
            escapehash: {
                "<": "&lt;",
                ">": "&gt;",
                "&": "&amp;",
                '"': "&quot;",
                "'": "&#x27;",
                "/": "&#x2f;"
            },
            escapereplace: function(k) {
                return __escapehtml.escapehash[k];
            },
            escaping: function(str) {
                return typeof str !== "string" ? str : str.replace(/[&<>"]/gim, this.escapereplace);
            },
            detection: function(data) {
                return typeof data === "undefined" ? "" : data;
            }
        };
        var __throw = function(error) {
            if (typeof console !== "undefined") {
                if (console.warn) {
                    console.warn(error);
                    return;
                }
                if (console.log) {
                    console.log(error);
                    return;
                }
            }
            throw error;
        };
        var __creator = function(o, proto) {
            o = o !== Object(o) ? {} : o;
            if (o.__proto__) {
                o.__proto__ = proto;
                return o;
            }
            var empty = function() {};
            var n = Object.create ? Object.create(proto) : new (empty.prototype = proto, empty)();
            for (var i in o) {
                if (o.hasOwnProperty(i)) {
                    n[i] = o[i];
                }
            }
            return n;
        };
        juicer.__cache = {};
        juicer.version = "0.6.4-stable";
        juicer.settings = {};
        juicer.tags = {
            operationOpen: "{@",
            operationClose: "}",
            interpolateOpen: "\\${",
            interpolateClose: "}",
            noneencodeOpen: "\\$\\${",
            noneencodeClose: "}",
            commentOpen: "\\{#",
            commentClose: "\\}"
        };
        juicer.options = {
            cache: true,
            strip: true,
            errorhandling: true,
            detection: true,
            _method: __creator({
                __escapehtml: __escapehtml,
                __throw: __throw,
                __juicer: juicer
            }, {})
        };
        juicer.tagInit = function() {
            var forstart = juicer.tags.operationOpen + "each\\s*([^}]*?)\\s*as\\s*(\\w*?)\\s*(,\\s*\\w*?)?" + juicer.tags.operationClose;
            var forend = juicer.tags.operationOpen + "\\/each" + juicer.tags.operationClose;
            var ifstart = juicer.tags.operationOpen + "if\\s*([^}]*?)" + juicer.tags.operationClose;
            var ifend = juicer.tags.operationOpen + "\\/if" + juicer.tags.operationClose;
            var elsestart = juicer.tags.operationOpen + "else" + juicer.tags.operationClose;
            var elseifstart = juicer.tags.operationOpen + "else if\\s*([^}]*?)" + juicer.tags.operationClose;
            var interpolate = juicer.tags.interpolateOpen + "([\\s\\S]+?)" + juicer.tags.interpolateClose;
            var noneencode = juicer.tags.noneencodeOpen + "([\\s\\S]+?)" + juicer.tags.noneencodeClose;
            var inlinecomment = juicer.tags.commentOpen + "[^}]*?" + juicer.tags.commentClose;
            var rangestart = juicer.tags.operationOpen + "each\\s*(\\w*?)\\s*in\\s*range\\(([^}]+?)\\s*,\\s*([^}]+?)\\)" + juicer.tags.operationClose;
            var include = juicer.tags.operationOpen + "include\\s*([^}]*?)\\s*,\\s*([^}]*?)" + juicer.tags.operationClose;
            juicer.settings.forstart = new RegExp(forstart, "igm");
            juicer.settings.forend = new RegExp(forend, "igm");
            juicer.settings.ifstart = new RegExp(ifstart, "igm");
            juicer.settings.ifend = new RegExp(ifend, "igm");
            juicer.settings.elsestart = new RegExp(elsestart, "igm");
            juicer.settings.elseifstart = new RegExp(elseifstart, "igm");
            juicer.settings.interpolate = new RegExp(interpolate, "igm");
            juicer.settings.noneencode = new RegExp(noneencode, "igm");
            juicer.settings.inlinecomment = new RegExp(inlinecomment, "igm");
            juicer.settings.rangestart = new RegExp(rangestart, "igm");
            juicer.settings.include = new RegExp(include, "igm");
        };
        juicer.tagInit();
        // Using this method to set the options by given conf-name and conf-value,
        // you can also provide more than one key-value pair wrapped by an object.
        // this interface also used to custom the template tag delimater, for this
        // situation, the conf-name must begin with tag::, for example: juicer.set
        // ('tag::operationOpen', '{@').
        juicer.set = function(conf, value) {
            var that = this;
            var escapePattern = function(v) {
                return v.replace(/[\$\(\)\[\]\+\^\{\}\?\*\|\.]/gim, function($) {
                    return "\\" + $;
                });
            };
            var set = function(conf, value) {
                var tag = conf.match(/^tag::(.*)$/i);
                if (tag) {
                    that.tags[tag[1]] = escapePattern(value);
                    that.tagInit();
                    return;
                }
                that.options[conf] = value;
            };
            if (arguments.length === 2) {
                set(conf, value);
                return;
            }
            if (conf === Object(conf)) {
                for (var i in conf) {
                    if (conf.hasOwnProperty(i)) {
                        set(i, conf[i]);
                    }
                }
            }
        };
        // Before you're using custom functions in your template like ${name | fnName},
        // you need to register this fn by juicer.register('fnName', fn).
        juicer.register = function(fname, fn) {
            var _method = this.options._method;
            if (_method.hasOwnProperty(fname)) {
                return false;
            }
            return _method[fname] = fn;
        };
        // remove the registered function in the memory by the provided function name.
        // for example: juicer.unregister('fnName').
        juicer.unregister = function(fname) {
            var _method = this.options._method;
            if (_method.hasOwnProperty(fname)) {
                return delete _method[fname];
            }
        };
        juicer.template = function(options) {
            var that = this;
            this.options = options;
            this.__interpolate = function(_name, _escape, options) {
                var _define = _name.split("|"), _fn = _define[0] || "", _cluster;
                if (_define.length > 1) {
                    _name = _define.shift();
                    _cluster = _define.shift().split(",");
                    _fn = "_method." + _cluster.shift() + ".call({}, " + [ _name ].concat(_cluster) + ")";
                }
                return "<%= " + (_escape ? "_method.__escapehtml.escaping" : "") + "(" + (!options || options.detection !== false ? "_method.__escapehtml.detection" : "") + "(" + _fn + ")" + ")" + " %>";
            };
            this.__removeShell = function(tpl, options) {
                var _counter = 0;
                tpl = tpl.replace(juicer.settings.forstart, function($, _name, alias, key) {
                    var alias = alias || "value", key = key && key.substr(1);
                    var _iterate = "i" + _counter++;
                    return "<% ~function() {" + "for(var " + _iterate + " in " + _name + ") {" + "if(" + _name + ".hasOwnProperty(" + _iterate + ")) {" + "var " + alias + "=" + _name + "[" + _iterate + "];" + (key ? "var " + key + "=" + _iterate + ";" : "") + " %>";
                }).replace(juicer.settings.forend, "<% }}}(); %>").replace(juicer.settings.ifstart, function($, condition) {
                    return "<% if(" + condition + ") { %>";
                }).replace(juicer.settings.ifend, "<% } %>").replace(juicer.settings.elsestart, function($) {
                    return "<% } else { %>";
                }).replace(juicer.settings.elseifstart, function($, condition) {
                    return "<% } else if(" + condition + ") { %>";
                }).replace(juicer.settings.noneencode, function($, _name) {
                    return that.__interpolate(_name, false, options);
                }).replace(juicer.settings.interpolate, function($, _name) {
                    return that.__interpolate(_name, true, options);
                }).replace(juicer.settings.inlinecomment, "").replace(juicer.settings.rangestart, function($, _name, start, end) {
                    var _iterate = "j" + _counter++;
                    return "<% ~function() {" + "for(var " + _iterate + "=" + start + ";" + _iterate + "<" + end + ";" + _iterate + "++) {{" + "var " + _name + "=" + _iterate + ";" + " %>";
                }).replace(juicer.settings.include, function($, tpl, data) {
                    return "<%= _method.__juicer(" + tpl + ", " + data + "); %>";
                });
                // exception handling
                if (!options || options.errorhandling !== false) {
                    tpl = "<% try { %>" + tpl;
                    tpl += '<% } catch(e) {_method.__throw("Juicer Render Exception: "+e.message);} %>';
                }
                return tpl;
            };
            this.__toNative = function(tpl, options) {
                return this.__convert(tpl, !options || options.strip);
            };
            this.__lexicalAnalyze = function(tpl) {
                var buffer = [];
                var method = [];
                var prefix = "";
                var reserved = [ "if", "each", "_", "_method", "console", "break", "case", "catch", "continue", "debugger", "default", "delete", "do", "finally", "for", "function", "in", "instanceof", "new", "return", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with", "null", "typeof", "class", "enum", "export", "extends", "import", "super", "implements", "interface", "let", "package", "private", "protected", "public", "static", "yield", "const", "arguments", "true", "false", "undefined", "NaN" ];
                var indexOf = function(array, item) {
                    if (Array.prototype.indexOf && array.indexOf === Array.prototype.indexOf) {
                        return array.indexOf(item);
                    }
                    for (var i = 0; i < array.length; i++) {
                        if (array[i] === item) return i;
                    }
                    return -1;
                };
                var variableAnalyze = function($, statement) {
                    statement = statement.match(/\w+/gim)[0];
                    if (indexOf(buffer, statement) === -1 && indexOf(reserved, statement) === -1 && indexOf(method, statement) === -1) {
                        // avoid re-declare native function, if not do this, template 
                        // `{@if encodeURIComponent(name)}` could be throw undefined.
                        if (typeof window !== "undefined" && typeof window[statement] === "function" && window[statement].toString().match(/^\s*?function \w+\(\) \{\s*?\[native code\]\s*?\}\s*?$/i)) {
                            return $;
                        }
                        // compatible for node.js
                        if (typeof global !== "undefined" && typeof global[statement] === "function" && global[statement].toString().match(/^\s*?function \w+\(\) \{\s*?\[native code\]\s*?\}\s*?$/i)) {
                            return $;
                        }
                        // avoid re-declare registered function, if not do this, template 
                        // `{@if registered_func(name)}` could be throw undefined.
                        if (typeof juicer.options._method[statement] === "function") {
                            method.push(statement);
                            return $;
                        }
                        buffer.push(statement);
                    }
                    return $;
                };
                tpl.replace(juicer.settings.forstart, variableAnalyze).replace(juicer.settings.interpolate, variableAnalyze).replace(juicer.settings.ifstart, variableAnalyze).replace(juicer.settings.elseifstart, variableAnalyze).replace(juicer.settings.include, variableAnalyze).replace(/[\+\-\*\/%!\?\|\^&~<>=,\(\)]\s*([A-Za-z_]+)/gim, variableAnalyze);
                for (var i = 0; i < buffer.length; i++) {
                    prefix += "var " + buffer[i] + "=_." + buffer[i] + ";";
                }
                for (var i = 0; i < method.length; i++) {
                    prefix += "var " + method[i] + "=_method." + method[i] + ";";
                }
                return "<% " + prefix + " %>";
            };
            this.__convert = function(tpl, strip) {
                var buffer = [].join("");
                buffer += "'use strict';";
                // use strict mode
                buffer += "var _=_||{};";
                buffer += "var _out='';_out+='";
                if (strip !== false) {
                    buffer += tpl.replace(/\\/g, "\\\\").replace(/[\r\t\n]/g, " ").replace(/'(?=[^%]*%>)/g, "	").split("'").join("\\'").split("	").join("'").replace(/<%=(.+?)%>/g, "';_out+=$1;_out+='").split("<%").join("';").split("%>").join("_out+='") + "';return _out;";
                    return buffer;
                }
                buffer += tpl.replace(/\\/g, "\\\\").replace(/[\r]/g, "\\r").replace(/[\t]/g, "\\t").replace(/[\n]/g, "\\n").replace(/'(?=[^%]*%>)/g, "	").split("'").join("\\'").split("	").join("'").replace(/<%=(.+?)%>/g, "';_out+=$1;_out+='").split("<%").join("';").split("%>").join("_out+='") + "';return _out.replace(/[\\r\\n]\\s+[\\r\\n]/g, '\\r\\n');";
                return buffer;
            };
            this.parse = function(tpl, options) {
                var _that = this;
                if (!options || options.loose !== false) {
                    tpl = this.__lexicalAnalyze(tpl) + tpl;
                }
                tpl = this.__removeShell(tpl, options);
                tpl = this.__toNative(tpl, options);
                this._render = new Function("_, _method", tpl);
                this.render = function(_, _method) {
                    if (!_method || _method !== that.options._method) {
                        _method = __creator(_method, that.options._method);
                    }
                    return _that._render.call(this, _, _method);
                };
                return this;
            };
        };
        juicer.compile = function(tpl, options) {
            if (!options || options !== this.options) {
                options = __creator(options, this.options);
            }
            try {
                var engine = this.__cache[tpl] ? this.__cache[tpl] : new this.template(this.options).parse(tpl, options);
                if (!options || options.cache !== false) {
                    this.__cache[tpl] = engine;
                }
                return engine;
            } catch (e) {
                __throw("Juicer Compile Exception: " + e.message);
                return {
                    render: function() {}
                };
            }
        };
        juicer.to_html = function(tpl, data, options) {
            if (!options || options !== this.options) {
                options = __creator(options, this.options);
            }
            return this.compile(tpl, options).render(data, options._method);
        };
        typeof module !== "undefined" && module.exports ? module.exports = juicer : this.juicer = juicer;
    })();
});